<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2021/08/24} {10:18} 
 */

namespace wanghua\general_utility_tools_php\wechat;


use Omnipay\Omnipay;
use think\Exception;
use wanghua\general_utility_tools_php\Mmodel;
use wanghua\general_utility_tools_php\tool\Tools;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;
use WeChatPay\Util\PemUtil;
use Yurun\PaySDK\Weixin\Params\PublicParams;
use Yurun\PaySDK\Weixin\Refund\Request;
use Yurun\PaySDK\Weixin\SDK;

/**
 * 微信支付逻辑
 * Class WechatPayLogic
 * @package app\index\logic
 */
class WechatPayLogic
{

    /**
     * @deprecated 废弃
     *
     * desc：调起h5支付
     *
     * composer包依赖: omnipay/common
     *
     * 其它工具包：wanghua/general-utility-tools-php
     *
     * author：wh
     * @param array $config 微信支付配置
     * @param array $order_info 订单信息
     * @param string $notify_url 回调通知URL
     * @return string 返回支付字符串，输出到浏览器进行支付
     */
    function h5pay(array $config, array $order_info, string $notify_url){

        $gateway = Omnipay::create('WechatPay_Mweb');
        $gateway->setAppId($config['app_id']);

        $gateway->setMchId(trim($config['mch_id']));
        $gateway->setApiKey($config['api_key']);

        $order_param = [
            'body'              => $order_info['goods_name'],
            'out_trade_no'      => $order_info['orderid'],
            'total_fee'         => $order_info['real_amount']*100, //=0.01  单位分
            'spbill_create_ip'  => request()->ip(),
            'fee_type'          => 'CNY',
            'notify_url'        => $notify_url,
            'trade_type'        => 'MWEB',
            'nonce_str'         => Tools::rand_str(),
        ];

        $request  = $gateway->purchase($order_param);

        $response = $request->send();

        $res_data = $response->getData();

        if($res_data['return_code'] != 'SUCCESS'){
            return '支付错误';
        }

        if($res_data['result_code'] != 'SUCCESS'){
            return '支付出错了';
        }


        $mweb_url = $res_data['mweb_url'];
        $pay_str = <<<EOF
<html><body><script type="text/javascript">location.href="{$mweb_url}"</script></body></html>
EOF;

        return $pay_str;

    }

    /**
     * @deprecated 废弃，SDK要报证书错误，实战推荐使用[yurunsoft/pay-sdk]库
     *
     * desc：微信jsapi支付
     * author：wh
     * @param $order
     * @param $notify_url
     * @return array
     */
    function wxJsApiPay($order,$notify_url){
        try {
            $config = wxConfOrderPayFirm();
            // 设置参数
            // 商户号
            $merchantId = $config['mch_id'];

            //dump($config);
            // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
            $merchantPrivateKeyFilePath = $config['merchantPrivateKeyFilePath'];//'file:///path/to/merchant/apiclient_key.pem';
            $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);

            // 「商户API证书」的「证书序列号」
            $merchantCertificateSerial = $config['merchantCertificateSerial'];//'3775B6A45ACD588826D15E583A95F5DD********';

            // 从本地文件中加载「微信支付平台证书」，用来验证微信支付应答的签名
            $mchCertificateFilePath = $config['mchCertificateFilePath'];//'file:///path/to/wechatpay/cert.pem';
            $platformPublicKeyInstance = Rsa::from($mchCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);

            // 从「微信支付平台证书」中获取「证书序列号」
            $platformCertificateSerial = PemUtil::parseCertificateSerialNo($mchCertificateFilePath);

            // 构造一个 APIv3 客户端实例
            $instance = Builder::factory([
                'mchid'      => $merchantId,
                'serial'     => $merchantCertificateSerial,
                'privateKey' => $merchantPrivateKeyInstance,
                'certs'      => [
                    $platformCertificateSerial => $platformPublicKeyInstance,
                ],
            ]);
            $resp = $instance
                ->chain('v3/pay/transactions/jsapi')
                ->post(['json' => [
                    'appid'        => $config['appid'],//【公众号ID】 公众号ID
                    'mchid'        => $config['mch_id'],//【直连商户号】 直连商户号
                    'description'  => $order['goods_name'],//【商品描述】 商品描述
                    'out_trade_no' => $order['orderid'],//【商户订单号】 商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一。
                    'notify_url'   => $notify_url,
                    'amount'       => [
                        'total'    => $order['real_amount']*100,//【总金额】 订单总金额，单位为分。
                        'currency' => 'CNY'
                    ],
                    'payer'=>[
                        'openid'   =>$order['openid']//【用户标识】 用户在普通商户AppID下的唯一标识。 下单前需获取到用户的OpenID
                    ],
                ]]);

            //echo $resp->getStatusCode(), PHP_EOL;
            //echo $resp->getBody(), PHP_EOL;

            $responseData = json_decode($resp->getBody(), true);

            // 构造JSAPI支付的参数
            $jsapiParameters = [
                'appId' => $config['appid'],
                'timeStamp' => (string)Formatter::timestamp(),
                'nonceStr' => Formatter::nonce(),
                'package' => 'prepay_id=' . $responseData['prepay_id'],
                'signType' => 'RSA-PSS',
            ];

            // 对JSAPI支付参数进行签名
            $jsapiParameters['paySign'] = Rsa::sign(
                Formatter::joinedByLineFeed(...array_values($jsapiParameters)),
                $merchantPrivateKeyInstance,
                'sha256'
            );

            // 返回JSAPI支付参数
            //header('Content-Type: application/json');
            //echo json_encode($jsapiParameters);
            //dump($jsapiParameters);

            return Tools::set_ok('ok',$jsapiParameters);
        } catch (\Exception $e) {
            Tools::error_txt_log($e);
            // 进行错误处理
            //echo $e->getMessage(), PHP_EOL;
            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                $r = $e->getResponse();
                //echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                //echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;

                $res_arr = json_decode($r->getBody(),true);
                return Tools::set_fail('异常.1',$res_arr);
            }
            //echo $e->getTraceAsString(), PHP_EOL;
            return Tools::set_fail('异常.2',$e->getMessage());
        }
    }
    /**
     * desc：微信jsapi支付，虽然文档不好用，但是可以正常支付
     *
     * 场景：微信内的网页支付
     *
     * composer包依赖：请安装[ yurunsoft/pay-sdk ]，附带自动安装yurunsoft/yurun-http包
     * 其它工具包：wanghua/general-utility-tools-php
     *
     * author：wh
     * @param array $config 微信支付的配置 必须参数：appid、mch_id、api_key
     * @param array $wx_user_info 微信用户信息 必须参数：openid
     * @param array $order_info 订单信息 必须参数：goods_name、orderid、goods_price(元)
     * @param string $notify_url 回调URL
     * @return false|string
     */
    function jsapiPay(array $config, array $wx_user_info, array $order_info, string $notify_url,$redirect_url=''){
        // 配置参数
        $params = new PublicParams();
        $params->appID = $config['appid']; // 支付平台分配给开发者的应用ID
        $params->mch_id = $config['mch_id']; // 微信支付分配的商户号
        $params->key = $config['api_key']; // API 密钥
        // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
        // $params->certPath = 'path/cert.pem'; // XXX: 绝对路径！！！
        // $params->keyPath = 'path/key';      // XXX: 绝对路径！！！！
        // 如果是子服务商需要配置
        // $params->sub_appid = ''; // 微信分配的子商户公众账号ID，服务商、银行服务商需要。
        // $params-> sub_mch_id  = ''; // 微信支付分配的子商户号，开发者模式下必填，服务商、银行服务商需要。
        // SDK实例化，传入公共配置
        $pay = new \Yurun\PaySDK\Weixin\SDK($params);
        // 支付接口（生成支付订单）
        $request = new \Yurun\PaySDK\Weixin\JSAPI\Params\Pay\Request;
        $request->body = $order_info['goods_name']; // 商品描述
        $request->out_trade_no = $order_info['orderid']; // 订单号
        $request->total_fee = $order_info['real_amount']*100; // 订单总金额，单位为：分
        $request->spbill_create_ip = request()->ip(); // 客户端ip
        $request->notify_url = $notify_url; // 异步通知地址
        $request->openid = $wx_user_info['openid']; // 必须设置openid
        if($redirect_url){
            $request->redirect_url = urlencode($redirect_url);
        }
        $request->profit_sharing = empty($order_info['profit_sharing'])?'N':$order_info['profit_sharing'];//是否分账N,Y
        // 调用接口
        $result = $pay->execute($request);
        //此调试代码禁止删除
        //var_dump('result:', $result);
        //var_dump('success:', $pay->checkResult());
        //var_dump('error:', $pay->getError(), 'error_code:', $pay->getErrorCode());
        if(!$pay->checkResult()){
            throw new Exception('下单错误.'.$pay->getError());
        }

        $request = new \Yurun\PaySDK\Weixin\JSAPI\Params\JSParams\Request;
        $request->prepay_id = $result['prepay_id'];
        $jsapiParams = $pay->execute($request);
        // 最后需要将数据传给js，使用WeixinJSBridge进行支付
        return json_encode($jsapiParams);
    }


    /**
     * desc： [推荐]微信退款，传入的金额保持“元”为单位，实际是以“分”的格式提交给微信支付
     *
     * 依赖：yurunsoft/pay-sdk
     *
     * author：wh
     * @param array $config 支付配置
     * @param array $order_info 订单信息
     * @param string $reason 退款原因（可选）
     * @return array
     */
    function toWxRefund($config,$order_info,$reason=''){
        return Mmodel::catch(function ()use($config,$order_info,$reason){
            // 配置参数
            $params = new PublicParams();
            $params->appID = $config['appid']; // 支付平台分配给开发者的应用ID
            $params->mch_id = $config['mch_id']; // 微信支付分配的商户号
            $params->key = $config['api_key']; // API 密钥
            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
            $params->certPath = $config['mchCertificateFilePath'];//'path/to/cert.pem'; // 证书路径
            $params->keyPath = $config['merchantPrivateKeyFilePath'];//'path/to/key'; // 密钥路径

            // 如果是子服务商需要配置
            // $params->sub_appid = ''; // 微信分配的子商户公众账号ID，服务商、银行服务商需要。
            // $params->sub_mch_id = ''; // 微信支付分配的子商户号，开发者模式下必填，服务商、银行服务商需要。

            // SDK实例化，传入公共配置
            $pay = new SDK($params);

            // 退款请求参数
            $request = new Request();
            $request->out_trade_no = $order_info['orderid']; // 原支付订单号
            $request->out_refund_no = $order_info['orderid']; // 商户退款单号
            $request->total_fee = $order_info['real_amount'] * 100; // 订单总金额，单位为：分
            $request->refund_fee = $order_info['real_amount'] * 100; // 退款金额，单位为：分

            try {
                // 调用退款接口
                Tools::log_to_write_txt(['调用退款接口，入参：orderid='.$order_info['orderid'],$request]);
                $result = $pay->execute($request);
                Tools::log_to_write_txt(['调用退款接口，出参：',$result]);
            }catch (\Exception $e){
                Tools::error_txt_log($e);
                return Tools::set_fail('[err]：'.$e->getMessage());
            }

            // 调试代码
            //var_dump('refund result:', $result);
            //var_dump('success:', $pay->checkResult());
            //var_dump('error:', $pay->getError(), 'error_code:', $pay->getErrorCode());

            //打印：$result
            //array(18) {
            //  ["return_code"] => string(7) "SUCCESS"
            //  ["return_msg"] => string(2) "OK"
            //  ["appid"] => string(18) "wx5904518b3a0b2965"
            //  ["mch_id"] => string(10) "1668824977"
            //  ["nonce_str"] => string(16) "3LyqioO7WmMEyFKk"
            //  ["sign"] => string(32) "6F0ECED3DED5F66200171B7050AFB635"
            //  ["result_code"] => string(7) "SUCCESS"
            //  ["transaction_id"] => string(28) "4200002407202408310164479484"
            //  ["out_trade_no"] => string(21) "phuzhe9n1725089504331"
            //  ["out_refund_no"] => string(21) "phuzhe9n1725089504331"
            //  ["refund_id"] => string(29) "50303600442024083127353984987"
            //  ["refund_channel"] => object(SimpleXMLElement)#63 (0) {
            //  }
            //  ["refund_fee"] => string(2) "10"
            //  ["coupon_refund_fee"] => string(1) "0"
            //  ["total_fee"] => string(2) "10"
            //  ["cash_fee"] => string(2) "10"
            //  ["coupon_refund_count"] => string(1) "0"
            //  ["cash_refund_fee"] => string(2) "10"
            //}
            //dump($result);
            if (!$pay->checkResult()) {
                Tools::log_to_write_txt([$pay]);
                return Tools::set_fail('退款错误：' . $pay->getError(),[$result,$pay]);
            }
            if($result['return_code'] == 'SUCCESS' && $result['result_code']=='SUCCESS'){
                return Tools::set_ok('退款成功',$result);
            }

            // 如果退款成功，$result 将包含退款操作的详细信息
            //echo "退款成功，退款单号：" . $request->out_refund_no;
            return Tools::set_fail('退款失败.',$result);
        });
    }

    /**
     * @deprecated 废弃，推荐使用toWxRefund方法
     *
     * SDK要报证书错误，实战推荐使用[yurunsoft/pay-sdk]库
     *
     * 微信退款，单位“分”
     *
     * 依赖：wechatpay/wechatpay微信支付推荐sdk
     *
     * 注意返回(message不是msg)：
     * [code:'RESOURCE_NOT_EXISTS','message':'订单不存在']
     *
     * 错误码：
     * SUCCESS: 退款成功
    CLOSED: 退款关闭
    PROCESSING: 退款处理中
    ABNORMAL: 退款异常
     *
     *
     * 代码经过测试没有问题，如果出现“The certs(xxxxxxxxxxxx) contains the merchant's certificate serial number(4xxxxxxxxxxxxx) which is not allowed here.”
     * 则是sdk代码问题，需要注释掉D:\wanghua\projects\meebo_mid\vendor\wechatpay\wechatpay\src\ClientJsonTrait.php
     * 大约文件中第225行代码。
     * 代码：
     *  //if (array_key_exists($config['serial'], $config['certs'])) {
     *  //    throw new Exception\InvalidArgumentException(sprintf(
     *  //        Exception\ERR_INIT_CERTS_EXCLUDE_MCHSERIAL, implode(',', array_keys($config['certs'])), $config['serial']
     *  //    ));
     *  //}
     */
    function wxRefund($order, $reason=''){
        $config = wxConfOrderPayFirm();
        // 设置参数
        // 商户号
        $merchantId = $config['mch_id'];

        //dump($config);
        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyFilePath = $config['merchantPrivateKeyFilePath'];//'file:///path/to/merchant/apiclient_key.pem';
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);

        // 「商户API证书」的「证书序列号」
        $merchantCertificateSerial = $config['merchantCertificateSerial'];//'3775B6A45ACD588826D15E583A95F5DD********';

        // 从本地文件中加载「微信支付平台证书」，用来验证微信支付应答的签名
        $mchCertificateFilePath = $config['mchCertificateFilePath'];//'file:///path/to/wechatpay/cert.pem';
        $platformPublicKeyInstance = Rsa::from($mchCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);

        // 从「微信支付平台证书」中获取「证书序列号」
        $platformCertificateSerial = PemUtil::parseCertificateSerialNo($mchCertificateFilePath);

        // 构造一个 APIv3 客户端实例
        $instance = Builder::factory([
            'mchid'      => $merchantId,
            'serial'     => $merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs'      => [
                $platformCertificateSerial => $platformPublicKeyInstance,
            ],
        ]);

        try {
            $promise = $instance
                ->chain('v3/refund/domestic/refunds')
                ->postAsync([
                    'json' => [
                        'out_trade_no' => $order['orderid'],
                        'out_refund_no'  => $order['orderid'],//退款单号 如果分批退款则单号必须每次唯一
                        'reason'        => $reason,
                        'amount'         => [
                            'refund'   => $order['real_amount']*100,//单位分
                            'total'    => $order['real_amount']*100,//单位分
                            'currency' => 'CNY',
                        ],
                    ],
                ])
                ->then(static function($response) {
                    // 正常逻辑回调处理
                    //dump(1111);
                    //echo $response->getBody(), PHP_EOL;

                    $res_arr = json_decode($response->getBody(),true);
                    return Tools::set_ok('ok',$res_arr);
                })
                ->otherwise(static function($e){
                    // 异常错误处理
                    //echo $e->getMessage(), PHP_EOL;
                    if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                        $r = $e->getResponse();
                        //echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                        //echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;
                        throw new Exception($r->getBody());
                    }
                    //echo $e->getTraceAsString(), PHP_EOL;

                    throw new Exception($e->getMessage());
                    //return Tools::set_res(5890,'退款失败'.$e->getMessage());
                });
            // 同步等待
            $promise->wait();
            //这里稍作注意,不清楚then返回会不会走这里（经测试现在不会）
        }catch (\Exception $e){
            Tools::error_txt_log($e);
            $json_decode = @json_decode($e->getMessage(),true);
            return Tools::set_res(5890,'退款错误.',$json_decode);
        }
    }
    /**
     *
     * [推荐]查询单笔退款
     *
     * 依赖：yurunsoft/pay-sdk
     *
     * 代码经过测试没有问题，如果出现“The certs(4xxxxxxxxxxxxx) contains the merchant's certificate serial number(4xxxxxxxxxxx) which is not allowed here.”
     * 则是sdk代码问题，需要注释掉D:\wanghua\projects\meebo_mid\vendor\wechatpay\wechatpay\src\ClientJsonTrait.php
     * 大约文件中第225行代码。
     * 代码：
     *   //if (array_key_exists($config['serial'], $config['certs'])) {
     *   //    throw new Exception\InvalidArgumentException(sprintf(
     *   //        Exception\ERR_INIT_CERTS_EXCLUDE_MCHSERIAL, implode(',', array_keys($config['certs'])), $config['serial']
     *   //    ));
     *   //}
     */
    function toWxRefundQuery($config, $outRefundNo)
    {
        return Mmodel::catch(function () use ($config, $outRefundNo) {
            // 配置参数
            $params = new PublicParams();
            $params->appID = $config['appid']; // 支付平台分配给开发者的应用ID
            $params->mch_id = $config['mch_id']; // 微信支付分配的商户号
            $params->key = $config['api_key']; // API 密钥

            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
            $params->certPath = $config['mchCertificateFilePath']; // 证书路径
            $params->keyPath = $config['merchantPrivateKeyFilePath']; // 密钥路径

            // SDK实例化，传入公共配置
            $pay = new \Yurun\PaySDK\Weixin\SDK($params);

            // 退款查询请求参数
            $request = new \Yurun\PaySDK\Weixin\RefundQuery\Request();
            $request->out_refund_no = $outRefundNo; // 商户退款单号

            // 调用退款查询接口
            Tools::log_to_write_txt(['调用退款查询接口，入参：outRefundNo=',$outRefundNo,$config]);
            $result = $pay->execute($request);
            Tools::log_to_write_txt(['调用退款查询接口，出参',$result]);

            // 调试代码
            if (!$pay->checkResult()) {
                throw new Exception('退款查询错误：' . $pay->getError());
            }

            if($result['return_code'] == 'SUCCESS' && $result['result_code']=='SUCCESS'){
                return Tools::set_ok('退款成功');
            }

            // 如果退款成功，$result 将包含退款操作的详细信息
            //echo "退款成功，退款单号：" . $request->out_refund_no;
            return Tools::set_fail('退款失败.',$result);
        });
    }
    /**
     * @deprecated 废弃，推荐使用toWxRefundQuery方法
     *
     * SDK要报证书错误，实战推荐使用[yurunsoft/pay-sdk]库
     *
     * 查询单笔退款
     *
     * 依赖：wechatpay/wechatpay微信支付推荐sdk
     *
     * 代码经过测试没有问题，如果出现“The certs(4xxxxxxxxxxxxx) contains the merchant's certificate serial number(4xxxxxxxxxxx) which is not allowed here.”
     * 则是sdk代码问题，需要注释掉D:\wanghua\projects\meebo_mid\vendor\wechatpay\wechatpay\src\ClientJsonTrait.php
     * 大约文件中第225行代码。
     * 代码：
     *   //if (array_key_exists($config['serial'], $config['certs'])) {
     *   //    throw new Exception\InvalidArgumentException(sprintf(
     *   //        Exception\ERR_INIT_CERTS_EXCLUDE_MCHSERIAL, implode(',', array_keys($config['certs'])), $config['serial']
     *   //    ));
     *   //}
     */
    function wxRefundQuery($orderid){
        $config = wxConfOrderPayFirm();
        // 设置参数
        // 商户号
        $merchantId = $config['mch_id'];

        //dump($config);
        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyFilePath = $config['merchantPrivateKeyFilePath'];//'file:///path/to/merchant/apiclient_key.pem';
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);

        // 「商户API证书」的「证书序列号」
        $merchantCertificateSerial = $config['merchantCertificateSerial'];//'3775B6A45ACD588826D15E583A95F5DD********';

        // 从本地文件中加载「微信支付平台证书」，用来验证微信支付应答的签名
        $mchCertificateFilePath = $config['mchCertificateFilePath'];//'file:///path/to/wechatpay/cert.pem';
        $platformPublicKeyInstance = Rsa::from($mchCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);

        // 从「微信支付平台证书」中获取「证书序列号」
        $platformCertificateSerial = PemUtil::parseCertificateSerialNo($mchCertificateFilePath);

        // 构造一个 APIv3 客户端实例
        $instance = Builder::factory([
            'mchid'      => $merchantId,
            'serial'     => $merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs'      => [
                $platformCertificateSerial => $platformPublicKeyInstance,
            ],
        ]);
        // 退款单号
        $outRefundNo = $orderid; // 商户系统内部的退款单号

        try {
            // 发起查询单笔退款请求
            $response = $instance->chain("v3/refund/domestic/refunds/{$outRefundNo}")->get();

            //echo $response->getStatusCode(), PHP_EOL;
            //echo $response->getBody(), PHP_EOL;
            $res_arr = json_decode($response->getBody(),true);
            return Tools::set_ok('ok',$res_arr);
        } catch (\Exception $e) {
            Tools::error_txt_log($e);
            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                $r = $e->getResponse();
                //echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                //echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;

                $res_arr = json_decode($r->getBody(),true);
                return Tools::set_fail('异常.',$res_arr);
            }
            //echo $e->getTraceAsString(), PHP_EOL;
            return Tools::set_fail('异常.',$e->getMessage());
        }
    }
}